package com.meizi.codegenerate.generate.clien.application.service.client;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.meizi.codegenerate.constant.AnnotationSettingValueConstant;
import com.meizi.codegenerate.constant.JavaClassNameConstant;
import com.meizi.codegenerate.constant.TableNameConstant;
import com.meizi.codegenerate.entity.ProjectPositionEntity;
import com.meizi.codegenerate.entity.TablesEntity;
import com.meizi.codegenerate.generate.clien.application.service.fallback.FallbackFactoryGenerate;
import com.meizi.codegenerate.packagegenerate.PackageGenerate;
import com.meizi.codegenerate.utils.AnnotationUtils;
import com.meizi.codegenerate.utils.AttributeConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.cloud.openfeign.FeignClient;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;

/**
 * @author pc
 * @date 2024/1/4 - 14:50 - 星期四
 * @project lambda
 * @package com.meizi.codegenerate.generate.clien.application.service.client
 * @by GGbomd猪猪侠
 */
@Slf4j
public class FeignGenerate {

    /**
     * 创建feign interface
     * @throws IOException
     */
    public static void createFeign (String tableName, TablesEntity tablesComment,
                                    ProjectPositionEntity projectPosition, String serviceClassName) throws IOException {

        // 在相应的路径下创建对应的文件
        String serviceUrl = PackageGenerate.obtainClientUrl(projectPosition);

        //获取Feign java类名
        String className = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, true)
                + JavaClassNameConstant.SERVICE_CLIENT;
        // 获取完成的文件路径创建文件
        String fullPath = serviceUrl + className + TableNameConstant.JAVA;
        log.info("创建 application 下feign路径 fullPath = {}", fullPath);

        CompilationUnit compilationUnit = new CompilationUnit();
        // 添加package
        compilationUnit.setPackageDeclaration(PackageGenerate.clientPackage(projectPosition));

        compilationUnit.addImport("org.springframework.cloud.openfeign.FeignClient");

        // 添加接口文件
        ClassOrInterfaceDeclaration declaration = compilationUnit.addInterface(className).setPublic(true);
        //添加类级别注释
        declaration.setJavadocComment(tablesComment.getTableComment() + " feignClient 远程调用");

        //获取FallbackFactory java类名
        String FallbackFactoryClassName = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, true)
                + JavaClassNameConstant.FALLBACK_FACTORY;
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();

        // 添加类级别注解
        map.put(AnnotationSettingValueConstant.FEIGNCLIENT_NAME, TableNameConstant.FeignClient_NAME);
        map.put(AnnotationSettingValueConstant.FEIGNCLIENT_FALLBACKFACTORY, FallbackFactoryClassName.getBytes());
        declaration.addAnnotation(AnnotationUtils.setAnnotation(FeignClient.class, new NodeList<>(),
                map));

        // 继承service
        declaration.addExtendedType(serviceClassName);

        log.info("生成feignClient接口 compilationUnit = {}", compilationUnit.toString());

        /**
         * 把字符串写入文件
         * 参数1：需要写入的文件，如果文件不存在，将自动创建。  参数2：需要写入的内容
         * 参数3：编码格式     参数4：是否为追加模式（ ture: 追加模式，把字符串追加到原内容后面）
         */
        FileUtils.writeStringToFile(new File(fullPath), compilationUnit.toString(), "UTF-8", false);

        // 生成FallbackFactory
        FallbackFactoryGenerate.createFallback(tableName, tablesComment, projectPosition, className);
    }
}
